function [best_Zi, best_acc, Fmin, stage,increment_num] = Bi_CSO(num_simple, num_iter, num_feature, data_x, data_y)
% 避免重复计算准确率
golbal_z = [];
golbal_acc = [];
increment_num = [];
% 初始化粒子群样本
X = rand(num_simple, num_feature);
% 将X转换成0/1
r1 = ones(num_simple, num_feature) * 0.5;
Z = zeros(num_simple, num_feature);
Z(r1 < X) = 1;
Z(r1 >= X) = 0;
V = X;
% 计算分类准确率
[Y, golbal_z, golbal_acc, increment_num] = evaluate(Z, data_x, data_y,golbal_z,golbal_acc,increment_num);
% 计算gbest,准确率最大的对应的索引
[fmin, ind1] = max(Y);
fprintf("iter 0 feature: X(%d,:) fmin: %.4f\n",ind1, fmin);

varphi = 0.1;
Fmin = zeros(num_iter, 1);
stage = zeros(num_iter, 1);

for i = 1 : num_iter
    PV = [];
    PX = [];
    PY = [];
    while ~isempty(X)
        m = size(X, 1);
        k1 = randi(m);
        k2 = randi(m);
        % 随机取两个不相同的个体
        while k2 == k1
            k2 = randi(m);
        end
        v1 = V(k1, :);
        x1 = X(k1, :);
        y1 = Y(k1, :);
        v2 = V(k2, :);
        x2 = X(k2, :);
        y2 = Y(k2, :);
        r1 = rand(1, num_feature);
        r2 = rand(1, num_feature);
        r3 = rand(1, num_feature);
        % loss就要更新
        if y1 >= y2
            PV = [PV; v1];
            PX = [PX; x1];
            PY = [PY; y1];
            v2 = r1 .* v2 + r2 .* (x1 - x2) + varphi * r3 .* ((x1 + x2) ./ 2 - x2);
            x2 = x2 + v2;
            x2(x2 > 1) = 1;
            x2(x2 < 0) = 0;
            %x2(x2 > 10) = 10;
            %x2(x2 < -10) = -10;
            %s = 1 ./ (1 + exp(-x2));
            % 增强了全局搜索的能力
            %r2 = rand(1, num_feature);
            r2 = ones(1, num_feature) * 0.5;
            z = zeros(1, num_feature);
            z(x2 > r2) = 1;
            z(x2 < r2) = 0;
            [y2, golbal_z, golbal_acc, increment_num] = evaluate(z, data_x, data_y,golbal_z,golbal_acc,increment_num);
            PV = [PV; v2];
            PX = [PX; x2];
            PY = [PY; y2];
        else
            PV = [PV; v2];
            PX = [PX; x2];
            PY = [PY; y2];
            v1 = r1 .* v1 + r2 .* (x2 - x1) + varphi * r3 .* ((x1 + x2) ./ 2 - x1);
            x1 = x1 + v1;
            x1(x1 > 1) = 1;
            x1(x1 < 0) = 0;
            %x1(x1 > 10) = 10;
            %x1(x1 < -10) = -10;
            %s = 1 ./ (1 + exp(-x1));
            %r3 = rand(1, num_feature);
            r3 = ones(1, num_feature) * 0.5;
            z = zeros(1, num_feature);
            z(x1 > r3) = 1;
            z(x1 < r3) = 0;
            [y1, golbal_z, golbal_acc, increment_num] = evaluate(z, data_x, data_y,golbal_z,golbal_acc,increment_num);
            PV = [PV; v1];
            PX = [PX; x1];
            PY = [PY; y1];
        end
        % 为了删除防止下标发生变化
        if k1 > k2
            V(k1, :) = [];
            X(k1, :) = [];
            Y(k1, :) = [];
            V(k2, :) = [];
            X(k2, :) = [];
            Y(k2, :) = [];
        else
            V(k2, :) = [];
            X(k2, :) = [];
            Y(k2, :) = [];
            V(k1, :) = [];
            X(k1, :) = [];
            Y(k1, :) = [];
        end
    end
    V = PV;
    X = PX;
    Y = PY;
    % 更新所有个体最佳位置
    [fmin, ind1] = max(Y);
    fprintf("iter %d feature: X(%d,:) fmin: %.4f\n",i, ind1, fmin);
    Fmin(i, 1) = fmin;
    r4 = ones(1, num_feature) * 0.5;
    z1 = zeros(1, num_feature);
    z1(r4 < X(ind1,:)) = 1;
    z1(r4 >= X(ind1,:)) = 0;
    stage(i, 1) = sum(z1(1, :));
end
best_Zi = z1;
best_acc = fmin;
end